package com.woniuxy.aspectj.anno;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @BelongsProject: java-85-course-code
 * @BelongsPackage: com.woniuxy.aspectj.anno
 * @Author: LiTongMiao
 * @Date: 2022/1/20 17:54
 * @Description: TODO
 */
@Aspect //aop要使用的 表示这个类是个 切面
@Component //这个是spring需要的，表示这个类是个 组件 可以自动帮我注册到IOC容器中成为bean 类似<bean id="myAnnoAspectJ" class="..">
public class MyAnnoAspectJ {
    @Pointcut("execution(* com.woniuxy.service.*.*(..))")
    private void myPointCut(){}
    //前置通知
    @Before("myPointCut()")
    public void myBefore(JoinPoint joinpoint){
        System.out.println("前置通知：模拟判断是否有@Transcational注解……");
        System.out.print("目标类是："+joinpoint.getTarget().getClass().getName());
        System.out.println("，被织入的增强目标的方法是："+joinpoint.getSignature().getName());
    }
    //后置通知
    @AfterReturning("myPointCut()")
    public void myAfterReturning(JoinPoint joinpoint){
        System.out.println("后置通知：模拟事务的提交……");
        System.out.print("目标类是："+joinpoint.getTarget());
        System.out.println("，被织入的增强目标的方法是："+joinpoint.getSignature().getName());
    }
    //环绕通知：不推荐使用
    @Around("myPointCut()")
    public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕开始：执行目标方法之前……");
        Object[] args = proceedingJoinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            args[i] = 0;
        }
        List proceed = (List) proceedingJoinPoint.proceed(args);
        proceed = new ArrayList<>();
        Map<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("a","你中病毒了！");
        objectObjectHashMap.put("b","请支付比特币…………0.09个");
        proceed.add(objectObjectHashMap);
        System.out.println("环绕结束：执行目标方法之后……");
        return proceed;
    }
    //异常通知
    @AfterThrowing(value = "myPointCut()",throwing = "e")
    public void myAfterThrowing(JoinPoint joinPoint,Throwable e){
        System.out.println("异常通知");
        System.out.println("报错信息"+e.getMessage());
    }
    //最终通知
    @After("myPointCut()")
    public void myAfter(){
        System.out.println("最终通知：模拟方法结束后释放资源，关闭SqlSession……");
    }
}